/*
 *
 * Created on: 19.09.2012
 *
 * log.cpp
 * This file is part of KOBUS
 * 
 * Copyright (C) 2012 - Ivan Penkin, MIPT
 * grek.penkin@gmail.com
 *
 * KOBUS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * KOBUS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with KOBUS; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 * Boston, MA  02110-1301  USA
 *  
 */

#include <log.h>
#include <log_p.h>
#include <qdaemonapplication.h>

#include <undefined_syslog.h>

using namespace kobus;

LogPrivate::LogPrivate(
               const QString & ident, int opt, int facility, QObject * parent)
    :QObject(parent),
     ident_char(ident.toLocal8Bit()) {

  openlog(ident_char.constData(), opt, facility);
}


LogPrivate::~LogPrivate() {

  closelog();
}


void LogPrivate::write(int prio, const char * format, va_list * valueList)
                    const {

  char * msg = new char[MAX_MSG_LENGTH];

  vsnprintf(msg, MAX_MSG_LENGTH, format, *valueList);
  syslog(prio, msg);

  delete[] msg;
}


void LogPrivate::write(int prio, const QString & msg) const {

  syslog(prio, msg.toLocal8Bit().constData());
}


LogPrivate * Log::d_ptr = NULL;

#ifdef _DEBUG_LEVEL
int          Log::debugLevel = _DEBUG_LEVEL;
#else
int          Log::debugLevel = 0;
#endif

Log::Log(QObject * parent)
    :QObject(parent) {

}

Log::Log(const QString & ident, Option opt, Facility facility, QObject * parent)
    :QObject(parent) {

  if (!d_ptr) {
    QObject * app = QDaemonApplication::instance();

    if (app)
      d_ptr = new LogPrivate(ident, opt, facility);
    else
      d_ptr = new LogPrivate(ident, opt, facility, app);
  }
}


Log::Log(LogPrivate * dd, QObject * parent)
    :QObject(parent) {

  d_ptr = dd;
}


Log::~Log() {

}


void Log::write(Priority prio, const char * format, ...) const {

  Q_D(const Log);
  if (!d)
    return;

  va_list valueList;
  va_start(valueList, format);

  d->write(prio, format, &valueList);

  va_end(valueList);
}


void Log::writeDebug(DebugLevel level, const char * format, ...) const {

#ifdef _DEBUG_LEVEL
  if (level <= debugLevel) {

    Q_D(const Log);
    if (!d)
      return;

    va_list valueList;
    va_start(valueList, format);

    d->write(LOG_DEBUG, format, &valueList);

    va_end(valueList);
  }
#endif
}


void Log::error(const char * format, ...) const {

  Q_D(const Log);
  if (!d)
    return;

  va_list valueList;
  va_start(valueList, format);

  d->write(LOG_ERR, format, &valueList);

  va_end(valueList);
}


void Log::warning(const char * format, ...) const {

  Q_D(const Log);
  if (!d)
    return;

  va_list valueList;
  va_start(valueList, format);

  d->write(LOG_WARNING, format, &valueList);

  va_end(valueList);
}


void Log::notice(const char * format, ...) const {

  Q_D(const Log);
  if (!d)
    return;

  va_list valueList;
  va_start(valueList, format);

  d->write(LOG_NOTICE, format, &valueList);

  va_end(valueList);
}


void Log::info(const char * format, ...) const {

  Q_D(const Log);
  if (!d)
    return;

  va_list valueList;
  va_start(valueList, format);

  d->write(LOG_INFO, format, &valueList);

  va_end(valueList);
}


void Log::write(Priority prio, const QString & msg) const {

  Q_D(const Log);
  if (!d)
    return;

  d->write(prio, msg);
}


void Log::writeDebug(DebugLevel level, const QString & msg) const {

#ifdef _DEBUG_LEVEL
  if (level <= debugLevel) {

    Q_D(const Log);
    if (!d)
      return;

    d->write(LOG_DEBUG, msg);
  }
#endif
}


void Log::error(const QString & msg) const {

  write(LOG_ERR, msg);
}


void Log::warning(const QString & msg) const {

  write(LOG_WARNING, msg);
}


void Log::notice(const QString & msg) const {

  write(LOG_NOTICE, msg);
}


void Log::info(const QString & msg) const {

  write(LOG_INFO, msg);
}
